`include "defines.svh"
`define MTVEC   12'h305
`define MEPC    12'h341
`define MCAUSE  12'h342
`define MSTATUS 12'h300
`define MTVAL   12'h343

module regfile_csr (
    input  logic        clk,
    input  logic        rst,

    input  logic        wen,
    input  rfcaddr_t    waddr, //独热写地址&写使能
    input  word_t       wdata,

    input  logic        en,
    input  rfcaddr_t    raddr,
    output word_t       rdata,

    input  logic        except_en,
    input  word_t       pc_i, //to mepc
    input  word_t       inst_i,//to mtval
    input  word_t       cause_i,//to mcause
    output word_t       mtvec_o,
    output word_t       mepc_o
);

word_t mtvec,mepc,mtval,mcause,mstatus;
word_t mvendorid, marchid;

always_ff @(posedge clk) begin
    if(rst == `ON) begin
        mtvec     <= `NULL;
        mepc      <= `NULL;
        mstatus   <= 'h1800;
        mtval     <= `NULL;
        mcause    <= `NULL;
        mvendorid <= 32'h79737978;
        marchid   <= 32'd23060094;
    end else if(except_en == `ON) begin
        mepc    <= pc_i;
        mtval   <= inst_i;
        mcause  <= cause_i;
    end else if(wen == `ON) begin
        case(waddr)
            `MTVEC   : mtvec   <= wdata;
            `MEPC    : mepc    <= wdata;
            `MCAUSE  : mcause  <= wdata;
            `MSTATUS : mstatus <= wdata;
            default  : mtval   <= wdata; //之后可以设计一个default异常，而不是默认赋值给mtval
        endcase
    end
end

always_comb begin
    if(rst == `ON || en == `OFF) begin
        rdata = `NULL;
    end else if(raddr == waddr && wen == `ON) begin
        rdata = wdata;
    end else begin
        case(raddr)
            `MTVEC   : rdata = mtvec;
            `MEPC    : rdata = mepc;
            `MCAUSE  : rdata = mcause;
            `MSTATUS : rdata = mstatus;
            default  : rdata = mtval; //之后可以设计一个default异常
        endcase
    end
    mtvec_o = mtvec;
    mepc_o  = mepc;
end

endmodule
